#include "EZ_Thread.h"

void memPort_Init(ez_memport_t *memPort, uint8_t	*memStart, uint32_t  memCnt, uint32_t  memSize)
{
	ipc_object_init(&memPort->ipc);
  
  memPort->memStart = memStart;
  memPort->memSize = memSize;

  list_init(&memPort->blockList);
  
  while(memCnt != 0)
  {
    list_init((list_t *)memStart);
    list_insert_before(&memPort->blockList,(list_t *)memStart);
    memStart += memSize;
		memCnt--;
  }

  
}

void memPort_getMem(ez_memport_t *memPort, uint8_t **mem)
{
	list_t *temp_node;
  if(list_isempty(&memPort->blockList) != EZ_TRUE)
  {
    temp_node =  memPort->blockList.next;
		list_remove(memPort->blockList.next);

    *mem = (uint8_t *)temp_node;
  }
}


uint32_t memPort_Take(ez_memport_t *memPort, uint8_t **mem, uint32_t time)
{
	uint32_t state;
	ez_thread_t *thread;

	state = ez_hw_interrupt_disable();

  if(list_isempty(&memPort->blockList) != EZ_TRUE)
  {
    memPort_getMem(memPort,mem);
  }
  else
  {
    if(time != 0)
    {
			thread = get_thread_self();
      ipc_object_wait(&memPort->ipc,thread,time);
			ez_hw_interrupt_enable(state);
			task_scheduler();
			memPort_Take(memPort, mem, 0);
    }
  }
  
	ez_hw_interrupt_enable(state);
	return EZ_TRUE;
}

void memPort_Release(ez_memport_t *memPort, uint8_t *mem)
{
	list_t *node;
	uint32_t state;

	state = ez_hw_interrupt_disable();

	node = (list_t *)mem;
	if(ipc_isempty(&memPort->ipc) != EZ_TRUE)
	{
		ipc_resume(&memPort->ipc.suspend_thread);
		ez_hw_interrupt_enable(state);
		task_scheduler();
	}
	else
	{
		list_insert_before(&memPort->blockList, node);

	}
	
	ez_hw_interrupt_enable(state);

}

  
